package com.qst.order.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qst.order.domain.DTO.ProductSubmitDTO;
import com.qst.order.domain.DTO.ReplenishRequest;
import com.qst.order.domain.DTO.UpdateStockDTO;
import com.qst.order.domain.Product;
import com.qst.order.domain.VO.ProductSpecVO;
import com.qst.order.service.ProductService;
import com.qst.order.service.ReplenishRecordService;
import com.qst.order.utils.JwtUtil;
import com.qst.order.utils.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/product")
@RequiredArgsConstructor
public class ProductController {

    private final ProductService productService;

    private final RedisTemplate<String, Object> redisTemplate;



    private final JwtUtil jwtUtil;

    @GetMapping
    public Result queryProducts(
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) BigDecimal minPrice,
            @RequestParam(required = false) BigDecimal maxPrice,
            @RequestParam(required = false) String sort,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "9") int pageSize) {

        log.info("查询参数：category={}, keyword={}, minPrice={}, maxPrice={}, sort={}, pageNum={}, pageSize={}",
                category, keyword, minPrice, maxPrice, sort, pageNum, pageSize);

        // 缓存未命中，查询数据库
        IPage<Product> allProducts;
        try {
            allProducts = productService.getAllProducts(category, keyword, minPrice, maxPrice, sort, pageNum, pageSize);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return Result.success(allProducts);
    }


    // 查询商品详情
    @GetMapping("/detail/{productId}")
    public Result<ProductSpecVO> queryProductDetail(@PathVariable(value = "productId") Integer productId) {
        log.info("查询商品详情，参数：productId={}", productId);
        ProductSpecVO specAndPriceByProductId = productService.getSpecAndPriceByProductId(productId);
        return Result.success(specAndPriceByProductId);
    }

    // 获取商品信息以及库存
    @GetMapping("/getStock")
    public Result getStock(@RequestParam(defaultValue = "1") Integer page,
                           @RequestParam(defaultValue = "8") Integer size,
                           @RequestParam(required = false) String keyword,
                           @RequestParam(required = false) String category,
                           @RequestParam(required = false) Integer status,
                           @RequestHeader(value = "Authorization") String token
    ) {
        log.info("获取商品信息以及库存，参数：page={}, size={}, keyword={}, category={}, status={}",
                page, size, keyword, category, status);
        Integer userId = Integer.valueOf(jwtUtil.getClaim(token, "userId"));
        IPage<Product> productIPage = new Page<>(page, size);
        IPage<Product> pageData = productService.getStock(productIPage, keyword, userId, category,status);
        return Result.success(pageData);
    }

    // 切换商品状态
    @PostMapping("/changeStatus/{productId}")
    public Result updateStatus(@PathVariable("productId") Integer productId) {
        try {
            // 调用服务层切换状态
            boolean success = productService.toggleStatus(productId);
            if (success) {
                return Result.success("状态切换成功");
            } else {
                return Result.error("商品不存在");
            }
        } catch (Exception e) {
            return Result.error("状态切换失败：" + e.getMessage());
        }
    }


    // 添加商品
    @PostMapping("/add")
    public Result addProduct(@RequestBody ProductSubmitDTO productSubmitDTO, @RequestHeader(value = "Authorization") String token) {
        Integer merchantId = Integer.valueOf(jwtUtil.getClaim(token, "userId"));
        log.warn("添加商品，参数：{}", productSubmitDTO);
        boolean success = productService.saveAndSpec(productSubmitDTO, merchantId);
        if (!success) {
            return Result.error("添加商品失败");
        }

        return Result.success();

    }

    //编辑商品
    @PostMapping("/{productId}")
    public Result editProduct(@RequestBody ProductSubmitDTO productSubmitDTO, @RequestHeader(value = "Authorization") String token) {

        Integer merchantId = Integer.valueOf(jwtUtil.getClaim(token, "userId"));
        log.warn("编辑商品，参数：{}", productSubmitDTO);
        boolean success = productService.UpdateProduct(productSubmitDTO, merchantId);
        return success ? Result.success() : Result.error("编辑商品失败");
    }


    @GetMapping("/merchant/warning")
    public Result<IPage<Product>> getWarningProducts(
            @RequestParam(defaultValue = "1") Integer page,  // 默认第1页
            @RequestParam(defaultValue = "10") Integer size,  // 默认每页10条
            @RequestParam(required = false) String keyword,   // 商品名称/ID搜索
            @RequestHeader(value = "Authorization") String token,
            @RequestParam(required = false) String category,  // 分类筛选
            @RequestParam(required = false) String level) {   // 预警级别（critical/warning/normal）

        Integer merchantId = Integer.valueOf(jwtUtil.getClaim(token, "userId"));
        // 调用服务层查询预警商品（分页）
        IPage<Product> productPage = productService.queryWarningProducts(
                page, size, keyword, category, level, merchantId);


        return Result.success(productPage);
    }

    @PostMapping("/updateStock")
    @Transactional   //调整库存
    @CacheEvict(value = "product", allEntries = true) // 清除所有列表缓存（因库存变化可能影响列表）
    public Result updateStock(@RequestBody UpdateStockDTO updateStockDTO) {
        productService.lambdaUpdate()
                .set(Product::getStock, updateStockDTO.getStock())
                .eq(Product::getProductId, updateStockDTO.getProductId())
                .update();
        return Result.success();
    }


}
